

#pragma once

#include "zadesk.h"
#include "zAdAChar.h"
#include "zAcValue.h"

class UcDbField;
class UcDbFieldCache;
class UcFdFieldResult;
class UcFdFieldEvaluator;
class UcFdFieldEvaluatorLoader;
class UcFdFieldEngine;
class UcFdFieldValue;
class UcFdImpFieldFormat;
class UcDbEvalVariant;

class UcFdFieldEvaluator : public UcRxObject
{
public:
    UCRX_DECLARE_MEMBERS(UcFdFieldEvaluator);

    UCDB_PORT UcFdFieldEvaluator(void);
    UCDB_PORT virtual ~UcFdFieldEvaluator(void);

    UCDB_PORT virtual const ZTCHAR * evaluatorId(void) const;
    UCDB_PORT virtual const ZTCHAR * evaluatorId(UcDbField* pField);

    UCDB_PORT virtual Ucad::ErrorStatus initialize(UcDbField* pField); 
    UCDB_PORT virtual Ucad::ErrorStatus compile(UcDbField* pField, 
                                             UcDbDatabase* pDb,
                                             UcFdFieldResult* pResult);
    UCDB_PORT virtual Ucad::ErrorStatus evaluate(UcDbField* pField, 
                                             int nContext, 
                                             UcDbDatabase* pDb, 
                                             UcFdFieldResult* pResult);
    UCDB_PORT virtual Ucad::ErrorStatus format(UcDbField* pField, 
                                             ZTCHAR *& pszValue);

protected:
    UcFdFieldEvaluator(void*);

protected:
    void        *   mpImpObj;

private:
    friend class UcFdSystemInternals;
};

class UcFdFieldEvaluatorLoader : public UcRxObject
{
public:
    UCRX_DECLARE_MEMBERS(UcFdFieldEvaluatorLoader);

    UCDB_PORT UcFdFieldEvaluatorLoader(void);
    UCDB_PORT UcFdFieldEvaluatorLoader(void*);    
    UCDB_PORT ~UcFdFieldEvaluatorLoader(void);

    UCDB_PORT virtual UcFdFieldEvaluator* getEvaluator(
                                                const ZTCHAR * pszEvalId);
    UCDB_PORT virtual UcFdFieldEvaluator * findEvaluator(UcDbField* pField,
                                             const ZTCHAR *& pszEvalId);

protected:
    void        *   mpImpObj;

private:
    friend class UcFdSystemInternals;
};

class UcFdFieldEngine : public UcRxObject
{
public:
    UCRX_DECLARE_MEMBERS(UcFdFieldEngine);

    UCDB_PORT UcFdFieldEngine();
    UCDB_PORT virtual ~UcFdFieldEngine();

    UCDB_PORT Ucad::ErrorStatus registerEvaluatorLoader(UcFdFieldEvaluatorLoader* pLoader);
    UCDB_PORT Ucad::ErrorStatus unregisterEvaluatorLoader(UcFdFieldEvaluatorLoader* pLoader);
    UCDB_PORT int   evaluatorLoaderCount    (void) const;
    UCDB_PORT UcFdFieldEvaluatorLoader * getEvaluatorLoader(int iIndex);
    UCDB_PORT UcFdFieldEvaluator * getEvaluator (const ZTCHAR * pszEvalId);
    UCDB_PORT UcFdFieldEvaluator * findEvaluator(UcDbField* pField, 
                                             const ZTCHAR *& pszEvalId);

protected:
    void        *   mpImpObj;

private:
    friend class UcFdSystemInternals;
};

class UcFdFieldResult : public UcRxObject
{
public:
    UCRX_DECLARE_MEMBERS(UcFdFieldResult);

    UcFdFieldResult(void);
    UCDB_PORT virtual Ucad::ErrorStatus setFieldValue(const UcValue* pValue);
    UCDB_PORT virtual Ucad::ErrorStatus setEvaluationStatus(int nStatus, 
                                             int dwErrCode = 0, 
                                             const ZTCHAR * pszMsg = NULL);
};

class UcFdFieldValue : public UcValue
{
public:
    UCRX_DECLARE_MEMBERS(UcFdFieldValue);

    UCDB_PORT UcFdFieldValue(void);
    UCDB_PORT UcFdFieldValue(UcFdFieldValue::DataType nDataType);
    UCDB_PORT UcFdFieldValue(const UcFdFieldValue& value);
    UCDB_PORT UcFdFieldValue(const ZTCHAR * pszValue);
    UCDB_PORT UcFdFieldValue(ZSoft::Int32 lValue);
    UCDB_PORT UcFdFieldValue(double fValue);
#ifdef _ZSOFT_WINDOWS_
    UCDB_PORT UcFdFieldValue(const __time64_t& date);
    UCDB_PORT UcFdFieldValue(const SYSTEMTIME& date);
#endif
    UCDB_PORT UcFdFieldValue(const UcGePoint2d& pt);
    UCDB_PORT UcFdFieldValue(double x, double y);
    UCDB_PORT UcFdFieldValue(const UcGePoint3d& pt);
    UCDB_PORT UcFdFieldValue(double x, double y, double z);
    UCDB_PORT UcFdFieldValue(const UcDbObjectId& id);
    UCDB_PORT UcFdFieldValue(const resbuf& rb);
    UCDB_PORT UcFdFieldValue(const UcDbEvalVariant& evalVar);
    UCDB_PORT UcFdFieldValue(const VARIANT& var);
    UCDB_PORT UcFdFieldValue(const void* pBuf, DWORD dwBufSize);
};

class UcFdFieldReactor : public UcRxObject
{
public:
    UCRX_DECLARE_MEMBERS(UcFdFieldReactor);

    virtual Ucad::ErrorStatus beginEvaluateFields(int nContext,
                                             UcDbDatabase* pDb);
    virtual Ucad::ErrorStatus endEvaluateFields(int nContext,
                                             UcDbDatabase* pDb);
};

typedef UcArray<UcFdFieldReactor*> FieldReactors;
Ucad::ErrorStatus   ucdbAddFieldReactor     (UcFdFieldReactor* pReactor);
Ucad::ErrorStatus   ucdbRemoveFieldReactor  (UcFdFieldReactor* pReactor);
